package com.yance.fim.core.handler.codec;


import com.yance.fim.core.enums.Code;
import com.yance.fim.core.enums.Command;
import com.yance.fim.core.handler.Codec;
import com.yance.fim.utils.ClassUtil;
import com.yance.fim.utils.Utility;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.HashMap;
import java.util.Map;


/**
 * @author yance
 */
public class WsMessageHandler {
    Logger logger = LoggerFactory.getLogger(WsMessageHandler.class);

    private Map<String, WsImHandler> wsHandlers = new HashMap();

    private static WsMessageHandler wsMessageHandler;

    public static WsMessageHandler getInstance() {
        if (wsMessageHandler == null) {
            synchronized (WsMessageHandler.class) {
                if (wsMessageHandler == null) {
                    wsMessageHandler = new WsMessageHandler();
                }
            }
        }
        return wsMessageHandler;
    }

    public WsMessageHandler() {
        registerAllHandler();
    }

    public byte[] handleRequest(Command cmd, Code code, String content) {
        WsImHandler wsImHandler = wsHandlers.get(cmd.name());
        if (wsImHandler == null) {
            wsImHandler = wsHandlers.get(code.name());
        }
        if (wsImHandler != null) {
            return wsImHandler.handleRequest(cmd, code, content);
        } else {
            return null;
        }
    }

    public String handleResult(Command cmd, Code code, byte[] body) {
        WsImHandler wsImHandler = wsHandlers.get(cmd.name());
        if (wsImHandler == null) {
            wsImHandler = wsHandlers.get(code.name());
        }
        if (wsImHandler != null) {
            return wsImHandler.handleResult(cmd, code, body);
        } else {
            return null;
        }
    }

    private void registerAllHandler() {
        try {
            for (Class cls : ClassUtil.getAllAssignedClass(WsImHandler.class)) {
                Codec annotation = (Codec) cls.getAnnotation(Codec.class);
                if (annotation != null) {
                    WsImHandler handler = (WsImHandler) cls.newInstance();
                    wsHandlers.put(annotation.value(), handler);
                }
            }
        } catch (Exception e) {
            Utility.printExecption(logger, e);
        }
    }
}
